package com.ziytek.web.citizen.listener;

import com.google.gson.Gson;
import com.ziytek.web.citizen.constant.NumConstant;
import com.ziytek.web.citizen.constant.ServerConstant;
import com.ziytek.web.citizen.event.DeviceRequestEvent;
import com.ziytek.web.citizen.service.DeviceRequestService;
import com.ziytek.web.citizen.util.HexUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;

/**
 * @author fenghx
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DeviceRequestEventListener {
    private final Gson gson;
    private final DeviceRequestService deviceRequestService;

    @Async("myAsyncExecutor")
    @EventListener
    @Order(ServerConstant.DATA_TYPE_LEN_1)
    public void deviceRequestEventListener(DeviceRequestEvent event) {
        Assert.notNull(event, "deviceRequestEventListener event is null");
        Assert.notNull(event.getDeviceRequestModel(), "deviceRequestEventListener event.model is null");
        Assert.notNull(event.getDeviceRequestModel().getB(), "deviceRequestEventListener event.model.b is null");

        var cab = event.getDeviceRequestModel().getB();
        var loadNum = event.getDeviceRequestModel().getS();
        var load = HexUtil.fillZero(Integer.toHexString(loadNum), NumConstant.INT_FOUR);
        log.info("设备断连重新请求业务,cab:{},load:{},event:{}", cab, load, gson.toJson(event));

        // 先转换为二进制 共16位长度
        var binary = HexUtil.fillZero(Integer.toBinaryString(loadNum), NumConstant.INT_TEN_SIX);
        log.info("二进制结果[{}]", binary);

        // 机柜号全部通道业务指令重新下发
        if (NumConstant.FF_NUM == loadNum) {
            log.info("设备断连重连业务请求,机柜号全部通道业务指令重新下发,cab:{},load:{}", cab, load);
            deviceRequestService.deviceRequestAllChannel(String.valueOf(cab));
            return;
        }

        // 单个板子的通道业务指令重新下发
        var size = binary.length();
        List<Integer> boardNos = new ArrayList<>();
        for (var i = size - NumConstant.INT_ONE; i >= NumConstant.INT_ZERO; i--) {
            var bit = Integer.parseInt(binary.substring(i, i + NumConstant.INT_ONE));
            if (bit > NumConstant.INT_ZERO) {
                boardNos.add(size - NumConstant.INT_ONE - i);
            }
        }

        if (boardNos.isEmpty()) {
            log.info("设备断连重连业务请求,机柜号单个恒流板业务指令重新下发失败,cab:{},load:{},boardNum(恒流板号减一):{}", cab, load, boardNos);
            return;
        }

        boardNos.sort(Integer::compareTo);
        log.info("设备断连重连业务请求,机柜号单个恒流板业务指令重新下发,cab:{},load:{},boardNum(恒流板号减一):{}", cab, load, gson.toJson(boardNos));

        deviceRequestService.deviceRequestSingleChannel(String.valueOf(cab), boardNos);
    }
}
